#!/usr/bin/env python
from standard_script_setup import *
from CIME.utils import copyifnewer, run_bld_cmd_ensure_logging, expect
from CIME.case import Case
from CIME.build import get_standard_makefile_args
import glob

logger = logging.getLogger(__name__)

def parse_command_line(args, description):
###############################################################################
    parser = argparse.ArgumentParser(
        usage="""\n{0} [--debug]
OR
{0} --verbose
OR
{0} --help

\033[1mEXAMPLES:\033[0m
    \033[1;32m# Run \033[0m
    > {0}
""" .format (os.path.basename(args[0])),

description=description,

formatter_class=argparse.ArgumentDefaultsHelpFormatter
)

    CIME.utils.setup_standard_logging_options(parser)

    parser.add_argument("buildroot",
                        help="build path root")

    parser.add_argument("installpath",
                        help="install path ")

    parser.add_argument("caseroot", nargs="?", default=os.getcwd(),
                        help="Case directory to build")

    args = CIME.utils.parse_args_and_handle_standard_logging_options(args, parser)

    return args.buildroot, args.installpath, args.caseroot


def buildlib(bldroot, installpath, case):
###############################################################################
    gmake_args = get_standard_makefile_args(case, shared_lib=True)
    comp_interface = case.get_value("COMP_INTERFACE")
    cimeroot = case.get_value("CIMEROOT")
    caseroot = case.get_value("CASEROOT")

    filepath = [os.path.join(caseroot,"SourceMods","src.share"),
                os.path.join(cimeroot,"src","share","streams"),
                os.path.join(cimeroot,"src","share","util"),
                os.path.join(cimeroot,"src","share","RandNum","src"),
                os.path.join(cimeroot,"src","share","RandNum","src","dsfmt_f03"),
                os.path.join(cimeroot,"src","share","RandNum","src","kissvec"),
                os.path.join(cimeroot,"src","share","RandNum","src","mt19937")]

    # Append path for driver - currently only values of 'mct' and 'nuopc' are accepted

    if comp_interface == "mct":
        filepath.append(os.path.join(cimeroot,"src","drivers","mct","shr"))
    elif comp_interface == "nuopc":
        filepath.append(os.path.join(cimeroot,"src","share","nuopc"))
        filepath.append(os.path.join(cimeroot,"src","share","streams_nuopc"))
    else:
        expect(False, "driver value of {} not supported".format(comp_interface))

    if case.get_value("USE_ESMF_LIB"):
        use_esmf = "esmf"
    else:
        use_esmf = "noesmf"
        filepath.append(os.path.join(cimeroot, "src", "share", "esmf_wrf_timemgr"))

    comp_interface = case.get_value("COMP_INTERFACE")
    ninst_value = case.get_value("NINST_VALUE")
    libdir = os.path.join(bldroot,comp_interface,use_esmf, ninst_value,"csm_share")
    if not os.path.isdir(libdir):
        os.makedirs(libdir)

    filepathfile = os.path.join(libdir, "Filepath")
    # if the filepathfile has a different number of lines than filepath, replace it
    file_len = 0
    if os.path.isfile(filepathfile):
        file_len = len(open(filepathfile).readlines())

    if len(filepath) != file_len:
        with open(filepathfile, "w") as fd:
            for path in filepath:
                fd.write("{}\n".format(path))

    components = case.get_values("COMP_CLASSES")
    multiinst_cppdefs = ""
    multi_driver = case.get_value("MULTI_DRIVER")
    for comp in components:
        if comp == "CPL":
            continue
        if multi_driver:
            ninst_comp = 1
        else:
            ninst_comp = case.get_value("NINST_{}".format(comp))
        multiinst_cppdefs += " -DNUM_COMP_INST_{}={}".format(comp, ninst_comp)

    if case.get_value("COMP_OCN") == "nemo":
        multiinst_cppdefs += " -DNEMO_IN_CCSM "

    installdir = os.path.join(installpath, comp_interface,
                              use_esmf, ninst_value)
    for ndir in ("lib", "include"):
        if not os.path.isdir(os.path.join(installdir,ndir)):
            os.makedirs(os.path.join(installdir,ndir))
    # copy some header files
    for _file in glob.iglob(os.path.join(cimeroot,"src","share","include","*")):
        copyifnewer(_file, os.path.join(installdir, "include", os.path.basename(_file)))
    for _file in glob.iglob(os.path.join(cimeroot,"src","share","RandNum","include","*")):
        copyifnewer(_file, os.path.join(installdir, "include", os.path.basename(_file)))

    # This runs the make command
    gmake_opts = "-f {}/Makefile complib MODEL=csm_share COMP_NAME=csm_share ".format(os.path.join(caseroot,"Tools"))
    gmake_opts += "-j {} ".format(case.get_value("GMAKE_J"))
    gmake_opts += " COMPLIB=libcsm_share.a"
    gmake_opts += ' USER_CPPDEFS="{} -DTIMING" '.format(multiinst_cppdefs)
    gmake_opts += "INCLUDE_DIR={} ".format(os.path.join(installdir, "include"))
    gmake_opts += gmake_args
    gmake_opts += " -C {}".format(libdir)

    gmake_cmd = case.get_value("GMAKE")

    cmd = "{} {}".format(gmake_cmd, gmake_opts)
    run_bld_cmd_ensure_logging(cmd, logger)

def _main(argv, documentation):
    bldroot, installpath, caseroot = parse_command_line(argv, documentation)
    with Case(caseroot) as case:
        buildlib(bldroot, installpath, case)

if (__name__ == "__main__"):
    _main(sys.argv, __doc__)
